package com.swotxu.mall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.swotxu.common.utils.HttpUtils;
import com.swotxu.common.utils.PageUtils;
import com.swotxu.common.utils.Query;
import com.swotxu.mall.member.dao.MemberDao;
import com.swotxu.mall.member.dao.MemberLevelDao;
import com.swotxu.mall.member.entity.MemberEntity;
import com.swotxu.mall.member.entity.MemberLevelEntity;
import com.swotxu.mall.member.exception.ExistException;
import com.swotxu.mall.member.exception.MemberLoginException;
import com.swotxu.mall.member.service.MemberService;
import com.swotxu.mall.member.vo.MemberLoginVo;
import com.swotxu.mall.member.vo.MemberRegistVo;
import com.swotxu.mall.member.vo.SocialUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


@Slf4j
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void regist(MemberRegistVo memberRegistVo) {
        // 检查用户名和手机号唯一
        checkMobileUnique(memberRegistVo.getPhone());
        checkUsernameUnique(memberRegistVo.getUserName());

        MemberEntity memberEntity = new MemberEntity();
        // 设置默认等级
        MemberLevelEntity levelEntity = memberLevelDao.getDefaultLevel();
        memberEntity.setLevelId(levelEntity.getId());
        memberEntity.setMobile(memberRegistVo.getPhone());
        memberEntity.setUsername(memberRegistVo.getUserName());
        memberEntity.setNickname(memberRegistVo.getUserName());
        // 密码加密存储
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        memberEntity.setPassword(encoder.encode(memberRegistVo.getPassword()));

        // 其他默认信息

        baseMapper.insert(memberEntity);
    }

    @Override
    public void checkEmailUnique(String email) throws ExistException {
        Integer count = baseMapper.selectCount(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getEmail, email));
        if (count > 0) {
            throw new ExistException.EmailExistException();
        }
    }

    @Override
    public void checkMobileUnique(String mobile) throws ExistException {
        Integer count = baseMapper.selectCount(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getMobile, mobile));
        if (count > 0) {
            throw new ExistException.MobileExistException();
        }
    }

    @Override
    public void checkUsernameUnique(String username) throws ExistException {
        Integer count = baseMapper.selectCount(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getUsername, username));
        if (count > 0) {
            throw new ExistException.UsernameExistException();
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo loginVo) throws MemberLoginException {
        String loginName = loginVo.getLoginacct();
        String password = loginVo.getPassword();
        // 获取数据库中用户对应的密码
        MemberEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<MemberEntity>()
                .eq(MemberEntity::getUsername, loginName).or()
                .eq(MemberEntity::getMobile, loginName));

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // 登陆失败
        if (entity == null || !encoder.matches(password, entity.getPassword())) {
            log.warn("用户名或密码错误，登陆失败! loginName: {}, password: {}", loginName, password);
            throw new MemberLoginException();
        }
        return entity;
    }

    @Override
    public MemberEntity login(SocialUser socialUser) throws MemberLoginException {
        // 注册和登陆逻辑
        // 1、判断当前社交用户是否已注册过
        MemberEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getSocialUid, socialUser.getUid()));
        // 已注册，则更新令牌即可
        if (entity != null) {
            MemberEntity updateEty = new MemberEntity();
            updateEty.setId(entity.getId());
            updateEty.setAccessToken(socialUser.getAccess_token());
            updateEty.setExpiresIn(socialUser.getExpires_in());
            // 更新微博来的用户信息
            getUserInfo(socialUser, updateEty);
            this.baseMapper.updateById(updateEty);

            entity.setAccessToken(socialUser.getAccess_token());
            entity.setExpiresIn(socialUser.getExpires_in());
            return entity;
        }
        // 2、未注册，则先注册再登录
        MemberEntity registEty = new MemberEntity();
        getUserInfo(socialUser, registEty);
        registEty.setSocialUid(socialUser.getUid());
        registEty.setAccessToken(socialUser.getAccess_token());
        registEty.setExpiresIn(socialUser.getExpires_in());
        // 设置默认等级
        registEty.setLevelId(memberLevelDao.getDefaultLevel().getId());

        this.baseMapper.insert(registEty);

        return registEty;
    }

    private void getUserInfo(SocialUser socialUser, MemberEntity registEty) {
        // 远程查询用户信息
        // 查询用户信息 GET https://api.weibo.com/2/users/show.json?access_token=2.00m3cPQG0Vfzy59b865053600ILCmz&uid=5736940772
        HashMap<String, String> map = Maps.newHashMap();
        map.put("access_token", socialUser.getAccess_token());
        map.put("uid", socialUser.getUid());
        try {
            HttpResponse httpResponse = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", HttpUtils.HTTP_GET, null, map);
            // 失败，重定向到登陆页
            if (httpResponse == null || httpResponse.getStatusLine().getStatusCode() != 200) {
                log.warn("远程获取用户信息失败！uid: {}, token: {}", socialUser.getUid(), socialUser.getAccess_token());
                return;
            }
            String bodyJsonStr = EntityUtils.toString(httpResponse.getEntity());
            JSONObject jsonObject = JSON.parseObject(bodyJsonStr);

            String name = jsonObject.getString("name"); // 昵称
            String gender = jsonObject.getString("gender"); // 性别
            String location = jsonObject.getString("location"); // city

            registEty.setUsername(name);
            registEty.setNickname(name);
            registEty.setGender("m".equalsIgnoreCase(gender)? 1 : 0);
            registEty.setCity(location);

        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }


}